///////////////////////////////////////////////////////////////////////////
//  Author:
//		Cameren Sales
///////////////////////////////////////////////////////////////////////////

#include "TicketHandler.h"
#include <iostream>


TicketHandler::TicketHandler()
	:m_ticketsReturned(0)
{
}
//Walker--Add
//TicketHandler::TicketHandler(int ElevCount, string fName, bool flag)
//	:m_ticketsReturned(0), stats(ElevCount, fName, flag)
//{
//
//}
TicketHandler::~TicketHandler()
{
}
void TicketHandler::createData()
{
	m_ticketList.clear();
	//Walker--Add
	//stats.init(runNum);
	Ticket ticket;
	int ID = 0;
	////////////////////////////////////////////////////////////////////////   
	// Workers arriving to work and leaving can edit number of workers now
	////////////////////////////////////////////////////////////////////////

	// workers going to floors 2-5(1-4) get to work 
	for(int i=0;i<NUM_OF_WORKERS;i++){
		int floor = (i%4)+1;
		ticket.generate(rand()%1800,0,floor,ID);			// arriving between 7:30-7:59
		m_ticketList.push_back(ticket);
		ID++;

		ticket.generate(rand()%1800+34200,floor,0,ID);	// leaving between 5:00 - 5:30
		m_ticketList.push_back(ticket);
		ID++;
	}

	////////////////////////////////////////////////////////////////////////   
	// Workers leave for lunch and return
	////////////////////////////////////////////////////////////////////////
	for(int i=0;i<WORKERS_LEAVE_FOR_LUNCH;i++){//pushing two tickets per
		int floor = rand()%4+1;//get a floor for the worker and return it to same floor

		ticket.generate(rand()%900+16200,floor,0,ID); //leaving for lunch
		m_ticketList.push_back(ticket);
		ID++;

		ticket.generate(rand()%900+18900,0,floor,ID); //returning time
		m_ticketList.push_back(ticket);
		ID++;
	}
	/////////// workers on lunch //////////////////////////////////////////

	////////////////////////////////////////////////////////////////////////   
	// Customers arrive throughout the day 
	// leaving 15-45 min after arrival
	////////////////////////////////////////////////////////////////////////
	for(int i=0;i<NUM_OF_CUSTUMERS;i++){
		int floor = rand()%4+1;					// get a floor for the customer to visit and leave from
		int time = rand()%31500 + 1800;			// get arrival time 

		ticket.generate(time,0,floor,ID); // arriving to building
		m_ticketList.push_back(ticket);
		ID++;

		ticket.generate(time+rand()%1800+900,floor,0,ID); // leaving
		m_ticketList.push_back(ticket);
		ID++;
	}
	//////// customers /////////////////////////////////////////////////////
	m_ticketsReturned = ID;
	//std::cout<<"Total tickets: "<<m_ticketsReturned<<endl;
	fillPQ();
}
bool TicketHandler::getTickets(vector<Ticket *> &tickets, int a_time)
{
	bool isThereTickets = false;
	// BUG Walker: Need to make sure queue is not empty
	// while(m_priorityQueue.top()->getArrival() == a_time)
	// Walker: Proposed fix
	while( (!m_priorityQueue.empty() ) && (m_priorityQueue.top()->getArrival() == a_time) )
	{
		tickets.push_back(m_priorityQueue.top());
		m_priorityQueue.pop();
		isThereTickets = true;
	}
	return isThereTickets;
}
void TicketHandler::fillPQ()
{
	while(!m_priorityQueue.empty())
		m_priorityQueue.pop();
	for(int i = 0; i<m_ticketList.size(); i++)
		m_priorityQueue.push(&m_ticketList[i]);
	//cout<<m_priorityQueue.size();
}
bool TicketHandler::simOver(){return !m_ticketsReturned;}
void TicketHandler::ticketClosed(){m_ticketsReturned--;}

//Walker--Delete the entire writeRunDataMethod
//// Write the data for this run to a file
//void TicketHandler::writeRunData(string FileBaseName, int runID)
//{
//	const string delimit = ",";
//	string fileName ="testR2.txt";
//	stringstream fName;
//	fName << FileBaseName << "R" << runID << ".txt";
//	fileName = fName.str();
//	cout << "File name is " << fileName << endl;
//	fstream runDataFile(fileName, ios::out | ios::trunc);
//	if ( runDataFile.is_open() )
//	{
//		runDataFile << "ID,Arrival Time,Service Time,Exit Time,Elev ID,Start Floor,Destination Floor,Wait Time" << endl;
//
//		for (auto data: m_ticketList)
//		{
//			runDataFile << data.getID() << delimit << data.getArrival() << delimit << data.getService() << delimit << data.getExitTime() << delimit << data.getElevator() << delimit << data.getStartFloor() << delimit << data.getDestination() << delimit << data.getService() - data.getArrival() << endl;
//		}
//		runDataFile.close();
//	}
//	else
//	{
//		cout << "File did not open" << endl;
//	}
//}
//
//Walker--ADD everything below
//// Write the data from the final analysis to a file
//void TicketHandler::writeFinalAnalysis()
//{
//	stats.writeSimData();
//}
//
////Walker:
//// Calculate and store the following data for each run:
////		Number of passengers delivered per elevator per floor 
////		Maximum and minimum Wait time
////		Wait time at 95% point (wait time at 95%--> .95 * 1410 = 1340)
////		Wait time not greater than 60 seconds percentage.
////	----For use with more than one run---
////		Maximum, minimum, and average passengers delivered per elevator per floor
////		Maximum and minimum Wait time for all runs
////		Maximum, minimum, and average 95% point 
////		Maximum, minimum, and average not greater than 60 second percentage.
//void TicketHandler::RunDataAnalysis(int runID)
//{
//	for (auto data : m_ticketList)
//	{
//		stats.processDataPoint(&data);
//	}
//	stats.CalcStats();
//}


